﻿using AiMoBridge.Interface;
using AiMoWindows.CodeScripts;
using AiMoWindows.CodeScripts.Analysis;
using AiMoWindows.MainActions.ScriptActions.SubActions;
using AiMoWindows.Windows.Scripts;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Text;
using RoslynPad.Editor;
using RoslynPad.Roslyn;
using System.Windows;
namespace AiMoWindows.MainActions.ScriptActions
{
    class ActionsController
    {
        #region Init
        public IDebugPrinter Printer { get; }
        public Window MainWindow { get; }
        public RoslynCodeEditor Editor { get; }
        public OpenSaveScriptAction OpenSaveAction { get; }
        public DownloadUploadScriptAction CodeToCloudAction { get; }
        public ClearScriptsAction ClearAction { get; }
        public AppendAdditionCodeAction AdditionCodeAction { get; }
        public FormatScriptAction FormatAction { get; }
        public CommentScriptsAction CommentAction { get; }
        public SyncScriptsAction SyncAction { get; }
        public ExecuteCodeAction ExecuteAction { get; }
        public NameMatchScriptAction NameMatchAction { get; }
        public MainButtonAction MainAction { get; }
        public DefinitionQuickAction DefinitionAction { get; }
        public CustomizedCompletionAction CompletionAction { get; }
        public Action ClearDebugPrint { get; }

        DocumentId? documentId;
        RoslynHost? scriptsHost;
        readonly ScriptManager scriptManager;
        public ActionsController(RoslynCodeEditor editor, ScriptManager scriptManager, ScriptWindow window)
        {
            Editor = editor;
            Printer = window;
            MainWindow = window;
            this.scriptManager = scriptManager;
            ClearDebugPrint = window.ClearPrintText;
            CommentAction = new CommentScriptsAction(this);
            FormatAction = new FormatScriptAction(this);
            SyncAction = new SyncScriptsAction(this, scriptManager);
            ExecuteAction = new ExecuteCodeAction(this, scriptManager);
            AdditionCodeAction = new AppendAdditionCodeAction(this, scriptManager);
            ClearAction = new ClearScriptsAction(this, scriptManager);
            CodeToCloudAction = new DownloadUploadScriptAction(this, scriptManager);
            OpenSaveAction = new OpenSaveScriptAction(this, scriptManager);
            NameMatchAction = new NameMatchScriptAction(this);
            DefinitionAction = new DefinitionQuickAction(this);
            MainAction = new MainButtonAction(this);
            CompletionAction = new CustomizedCompletionAction(this);

            //FormatAction.SetGetKeyAction(window.GetLastPressedKey);
        }

        public RoslynHost ScriptsHost => scriptsHost ?? throw new InvalidOperationException("Document not initialized");
        public DocumentId DocumentId => documentId ?? throw new InvalidOperationException("Document not initialized");
        /// <summary>
        /// 获取当前选择的文字Span
        /// </summary>
        public TextSpan CurrentSelectionSpan => new TextSpan(Editor.SelectionStart, Editor.SelectionLength);

        public Document CurrentDocument => ScriptsHost.GetDocument(DocumentId) ?? throw new InvalidOperationException("Document not initialized");
        public Project CurrentProject => ScriptsHost.GetDocument(DocumentId)?.Project ?? throw new InvalidOperationException("Document not initialized");
        public async Task<Compilation> GetCurrentCompilation() => await CurrentProject.GetCompilationAsync() ?? throw new InvalidOperationException("Document not initialized");
        /// <summary>
        /// 获取当前的Root
        /// </summary>
        public async Task<SyntaxNode> GetCurrentSyntaxRoot() => await CurrentDocument.GetSyntaxRootAsync().ConfigureAwait(false) ?? throw new InvalidOperationException("Document not initialized");
        public async Task<SyntaxToken> GetCurrentSelectSyntaxToken() => await CurrentDocument.GetTouchingWordAsync(CurrentSelectionSpan.Start, default).ConfigureAwait(false);
        public async Task<SourceText> CurrentSourceText() => await CurrentDocument.GetTextAsync();

        public async Task Initialize(RoslynHost roslynHost, DocumentId documentId)
        {
            scriptsHost = roslynHost;
            this.documentId = documentId;

            UsingFixLibrary.Init();

            if (!await SyncAction.SyncScriptsWithFormat())
            {
                MessageBox.Show(MainWindow, "Initialize script with wrong format", "Warning");
            }
            scriptManager.SetSaveCodeHash();
            InitState();
        }
        #endregion

        #region ShowProperties

        public void ShowProperties()
        {
            // 实现显示属性的逻辑
            Windows.Properties.PropertiesWindow propertiesWindow = new Windows.Properties.PropertiesWindow(scriptManager.Script, scriptManager.AllReferences);
            if (propertiesWindow.ShowDialog() == true)
            {
                if (propertiesWindow.GetAuthorChanged(out string newAuthor) | propertiesWindow.GetDescriptionChanged(out string newDescription))
                {
                    scriptManager.Script.SetAuthorAndDescription(newAuthor, newDescription);
                }
            }
        }

        #endregion

        #region State
        SyncScriptState syncState = SyncScriptState.NotInit;
        public SyncScriptState SyncState => syncState;
        public void InitState()
        {
            if (HasState(SyncScriptState.NotInit))
                syncState = SyncScriptState.None;
        }
        public void RemoveState(SyncScriptState toRemove)
        {
            if (syncState.HasFlag(toRemove))
            {
                syncState ^= toRemove;
            }
        }
        /// <summary>
        /// 如果之前已经包含新增状态，则返回True
        /// </summary>
        public void AddState(SyncScriptState toAdd)
        {
            syncState |= toAdd;
        }
        public bool HasState(SyncScriptState test)
        {
            return syncState.HasFlag(test);
        }
        #endregion



    }
}
